#include "CCReactor.h"
#include "global.h"
#include <signal.h>
#include <chrono>
#include <thread>

CCReactor::CCReactor() 
    : running(false), stop_requested(false), timer_interval_ms(100) {
}

CCReactor::~CCReactor() {
    Stop();
}

int CCReactor::Init() {
    if (poller.Init() != ERR_SUCCESS) {
        GlobalUtils::LogError("Failed to initialize poller");
        return ERR_POLL;
    }
    
    SetupSignalHandlers();
    GlobalUtils::LogInfo("Reactor initialized successfully");
    return ERR_SUCCESS;
}

int CCReactor::Start() {
    if (running) {
        GlobalUtils::LogWarning("Reactor is already running");
        return ERR_SUCCESS;
    }
    
    running = true;
    stop_requested = false;
    
    event_thread = std::thread(&CCReactor::EventLoop, this);
    
    GlobalUtils::LogInfo("Reactor event loop started");
    return ERR_SUCCESS;
}

int CCReactor::Stop() {
    if (!running) {
        return ERR_SUCCESS;
    }
    
    stop_requested = true;
    running = false;
    
    if (event_thread.joinable()) {
        event_thread.join();
    }
    
    GlobalUtils::LogInfo("Reactor event loop stopped");
    return ERR_SUCCESS;
}

int CCReactor::AddObject(CPollerObject* obj) {
    if (!obj) {
        return ERR_SOCKET;
    }
    
    return poller.AddObject(obj);
}

int CCReactor::RemoveObject(CPollerObject* obj) {
    if (!obj) {
        return ERR_SOCKET;
    }
    
    return poller.RemoveObject(obj);
}

void CCReactor::EventLoop() {
    GlobalUtils::LogInfo("Event loop started");
    
    while (running && !stop_requested && !g_shutdown_requested) {
        // Process timers
        ProcessTimers();
        
        // Calculate next timeout
        int timeout_ms = CTimerManager::Instance().GetNextTimeout();
        if (timeout_ms < 0) {
            timeout_ms = timer_interval_ms; // Default timeout
        } else if (timeout_ms > timer_interval_ms) {
            timeout_ms = timer_interval_ms; // Cap at our interval
        }
        
        // Wait for events
        int result = poller.WaitEvents(timeout_ms);
        if (result < 0) {
            GlobalUtils::LogError("Poller wait failed");
            break;
        }
        
        // Process events
        poller.ProcessEvents();
        
        // Call event callback if set
        if (event_callback) {
            event_callback();
        }
    }
    
    GlobalUtils::LogInfo("Event loop ended");
}

void CCReactor::ProcessTimers() {
    CTimerManager::Instance().ProcessTimers();
}

void CCReactor::SetupSignalHandlers() {
    // Setup signal handlers for graceful shutdown
    signal(SIGINT, [](int) {
        GlobalUtils::LogInfo("Received SIGINT, shutting down...");
        g_shutdown_requested = true;
    });
    
    signal(SIGTERM, [](int) {
        GlobalUtils::LogInfo("Received SIGTERM, shutting down...");
        g_shutdown_requested = true;
    });
}

CCReactor& CCReactor::Instance() {
    static CCReactor instance;
    return instance;
}

CCReactor* g_reactor = &CCReactor::Instance();